<?php
namespace app\service\recharge;

use think\facade\Db;
use EasyWeChat\Factory;
use app\service\PointsService;
use think\facade\Log;

class RechargeService
{
    protected $config;
    protected $app;
    protected $pointsService;
    
    // 最小充值积分
    const MIN_POINTS = 10;

    // 订单状态
    const ORDER_STATUS_PENDING = 0;    // 待支付
    const ORDER_STATUS_PAID = 1;       // 已支付
    const ORDER_STATUS_COMPLETED = 2;  // 已完成（已加积分）
    const ORDER_STATUS_FAILED = -1;    // 失败

    public function __construct()
    {
        $this->config = [
            'app_id' => config('wechat.payment.app_id'),
            'mch_id' => config('wechat.payment.mch_id'),
            'key' => config('wechat.payment.key'),
            'cert_path' => config('wechat.payment.cert_path'),
            'key_path' => config('wechat.payment.key_path'),
            'notify_url' => config('wechat.payment.notify_url'),
        ];
        $this->app = Factory::payment($this->config);
        $this->pointsService = new PointsService();
    }

    /**
     * 获取充值套餐列表
     */
    public function getPackageList()
    {
        // 默认充值套餐
        $packages = [
            [
                'id' => 1,
                'name' => '体验套餐',
                'points' => 100,
                'price' => 10.00,
                'description' => '适合新用户体验',
                'bonus' => 0,
                'status' => 1
            ],
            [
                'id' => 2,
                'name' => '基础套餐',
                'points' => 500,
                'price' => 45.00,
                'description' => '日常使用推荐',
                'bonus' => 50,
                'status' => 1
            ],
            [
                'id' => 3,
                'name' => '超值套餐',
                'points' => 1000,
                'price' => 80.00,
                'description' => '性价比之选',
                'bonus' => 200,
                'status' => 1
            ],
            [
                'id' => 4,
                'name' => '豪华套餐',
                'points' => 2000,
                'price' => 150.00,
                'description' => '重度用户首选',
                'bonus' => 500,
                'status' => 1
            ]
        ];

        return $packages;
    }

    /**
     * 根据套餐ID获取套餐信息
     */
    public function getPackageById($packageId)
    {
        $packages = $this->getPackageList();
        foreach ($packages as $package) {
            if ($package['id'] == $packageId) {
                return $package;
            }
        }
        return null;
    }

    /**
     * 创建充值订单
     * @param int $userId 用户ID
     * @param int $packageId 套餐ID（可选）
     * @param int $points 自定义充值积分数量（可选）
     * @throws \Exception
     */
    public function createOrder($userId, $packageId = null, $points = null)
    {
        if ($packageId) {
            // 使用套餐
            $package = $this->getPackageById($packageId);
            if (!$package) {
                throw new \Exception('充值套餐不存在');
            }
            $points = $package['points'] + $package['bonus'];
            $amount = $package['price'];
            $description = $package['name'];
        } else {
            // 自定义充值
            // if (!$points || $points < self::MIN_POINTS) {
                // throw new \Exception('最低充值' . self::MIN_POINTS . '积分');
            // }
            // 1积分 = 1元
            $amount = $points;
            $description = "充值{$points}积分";
        }

        // 生成订单号
        $orderNo = date('YmdHis') . mt_rand(1000, 9999);

        // 创建订单
        $order = [
            'order_no' => $orderNo,
            'user_id' => $userId,
            'package_id' => $packageId ?? 0,
            'points' => $points,
            'price' => $amount,
            'pay_type' => 'wxpay',
            'status' => self::ORDER_STATUS_PENDING,
            'create_time' => date('Y-m-d H:i:s')
        ];

        Db::name('recharge_order')->insert($order);

        // 调用微信支付创建二维码支付
        $result = $this->app->order->unify([
            'body' => $description,
            'out_trade_no' => $orderNo,
            'total_fee' => intval($amount * 100), // 转换为分
            'trade_type' => 'NATIVE',
            'product_id' => $orderNo
        ]);

        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            return [
                'order_no' => $orderNo,
                'points' => $points,
                'amount' => $amount,
                'payment_url' => $result['code_url'], // 需要生成二维码的支付链接
                'qrcode_data' => $result['code_url'], // 二维码数据（前端用此生成二维码图片）
                'description' => $description
            ];
        }

        throw new \Exception($result['err_code_des'] ?? '创建支付订单失败');
    }

    /**
     * 处理支付回调
     */
    public function handleNotify($message)
    {
        // 记录回调数据
        Log::info('微信支付回调数据：' . json_encode($message, JSON_UNESCAPED_UNICODE));

        if ($message['return_code'] === 'SUCCESS' && $message['result_code'] === 'SUCCESS') {
            $orderNo = $message['out_trade_no'];
            $transactionId = $message['transaction_id'];

            Log::info("开始处理订单：{$orderNo}, 微信交易号：{$transactionId}");

            Db::startTrans();
            try {
                // 使用悲观锁查询订单
                $order = Db::name('recharge_order')
                    ->where('order_no', $orderNo)
                    ->lock(true)
                    ->find();

                if (!$order) {
                    Log::error("订单不存在：{$orderNo}");
                    Db::rollback();
                    return false;
                }

                // 检查订单状态，避免重复处理
                if ($order['status'] !== self::ORDER_STATUS_PENDING) {
                    Log::info("订单状态不是待支付：{$orderNo}, 当前状态：{$order['status']}");
                    Db::rollback();
                    return true;
                }

                // 检查支付金额是否正确（微信支付金额单位为分）
                $totalFee = $message['total_fee'];
                if ($totalFee != $order['price'] * 100) {
                    Log::error("支付金额不匹配：订单金额：{$order['price']}元, 支付金额：{$totalFee}分");
                    // 记录错误日志
                    Db::name('recharge_order')
                        ->where('id', $order['id'])
                        ->update([
                            'status' => self::ORDER_STATUS_FAILED,
                            'transaction_id' => $transactionId,
                            'pay_time' => date('Y-m-d H:i:s'),
                            'error_msg' => "支付金额不匹配：订单金额：{$order['price']}元, 支付金额：{$totalFee}分"
                        ]);
                    Db::rollback();
                    return false;
                }

                Log::info("开始更新订单状态为已支付");

                // 1. 先标记订单为已支付
                $updateResult = Db::name('recharge_order')
                    ->where('id', $order['id'])
                    ->where('status', self::ORDER_STATUS_PENDING)
                    ->update([
                        'status' => self::ORDER_STATUS_PAID,
                        'transaction_id' => $transactionId,
                        'pay_time' => date('Y-m-d H:i:s')
                    ]);

                if (!$updateResult) {
                    Log::error("更新订单状态失败");
                    Db::rollback();
                    return true;
                }

                Log::info("开始添加用户积分");

                // 2. 使用 PointsService 增加积分
                $this->pointsService->recharge(
                    $order['user_id'],
                    $order['points'],
                    $orderNo,
                    "充值{$order['points']}积分"
                );

                Log::info("积分添加成功，更新订单状态为已完成");

                // 3. 最后标记订单为完成状态
                Db::name('recharge_order')
                    ->where('id', $order['id'])
                    ->update([
                        'status' => self::ORDER_STATUS_COMPLETED
                    ]);

                Db::commit();
                Log::info("订单处理完成：{$orderNo}");
                Log::save();
                return true;

            } catch (\Exception $e) {
                Log::error("处理订单异常：" . $e->getMessage());
                Db::rollback();
                // 记录错误日志
                Db::name('recharge_order')
                    ->where('order_no', $orderNo)
                    ->update([
                        'status' => self::ORDER_STATUS_FAILED,
                        'error_msg' => $e->getMessage()
                    ]);
                return false;
            }
        } else {
            Log::error('微信支付回调失败：' . ($message['return_msg'] ?? '未知错误'));
        }

        return false;
    }

    /**
     * 查询订单
     */
    public function queryOrder($orderNo, $userId = null)
    {
        $query = Db::name('recharge_order')->where('order_no', $orderNo);
        
        if ($userId) {
            $query->where('user_id', $userId);
        }
        
        $order = $query->find();
        
        if ($order) {
            // 格式化状态文本
            $statusMap = [
                self::ORDER_STATUS_PENDING => '待支付',
                self::ORDER_STATUS_PAID => '已支付',
                self::ORDER_STATUS_COMPLETED => '已完成',
                self::ORDER_STATUS_FAILED => '失败'
            ];
            $order['status_text'] = $statusMap[$order['status']] ?? '未知状态';
        }
        
        return $order;
    }

    /**
     * 获取用户充值记录
     */
    public function getUserOrders($userId, $page = 1, $pageSize = 10)
    {
        return Db::name('recharge_order')
            ->where('user_id', $userId)
            ->order('create_time', 'desc')
            ->page($page, $pageSize)
            ->select()
            ->each(function($order) {
                $statusMap = [
                    self::ORDER_STATUS_PENDING => '待支付',
                    self::ORDER_STATUS_PAID => '已支付',
                    self::ORDER_STATUS_COMPLETED => '已完成',
                    self::ORDER_STATUS_FAILED => '失败'
                ];
                $order['status_text'] = $statusMap[$order['status']] ?? '未知状态';
                return $order;
            });
    }

    /**
     * 获取支付实例
     */
    public function getPayApp()
    {
        return $this->app;
    }
} 